ditto
struct Foo {} enum msg = isInputRangeErrorFormatter!(Foo); enum exp =`Foo is not an InputRange because: the property 'empty' does not exist and the property 'front' does not exist and the function 'popFront' does not exist`; static assert(msg == exp, msg ~ "\n" ~ exp); string msg2 = isInputRangeErrorFormatter!(Foo); assert(msg2 == exp, msg ~ "\n" ~ exp);
ditto
struct Foo { int empty; } enum msg = isInputRangeErrorFormatter!(Foo); enum exp =`Foo is not an InputRange because: the property 'empty' is not of type 'bool' but 'int' and the property 'front' does not exist and the function 'popFront' does not exist`; static assert(msg == exp, msg ~ "\n" ~ exp); string msg2 = isInputRangeErrorFormatter!(Foo); assert(msg2 == exp, msg ~ "\n" ~ exp);
ditto
struct Foo { bool empty; void front(); } enum msg = isInputRangeErrorFormatter!(Foo); enum exp =`Foo is not an InputRange because: the property 'front' does not return a non 'void' value and the function 'popFront' does not exist`; static assert(msg == exp, msg ~ "\n" ~ exp); string msg2 = isInputRangeErrorFormatter!(Foo); assert(msg2 == exp, msg ~ "\n" ~ exp);
ditto
struct Foo { bool empty; int front(); } enum msg = isInputRangeErrorFormatter!(Foo); enum exp =`Foo is not an InputRange because: the function 'popFront' does not exist`; static assert(msg == exp, msg ~ "\n" ~ exp); string msg2 = isInputRangeErrorFormatter!(Foo); assert(msg2 == exp, msg ~ "\n" ~ exp);
ditto
struct Foo { bool empty; int front(); void popFront(); } enum msg = isInputRangeErrorFormatter!(Foo); enum exp =`Foo is an InputRange`; static assert(msg == exp, msg ~ "\n" ~ exp); string msg2 = isInputRangeErrorFormatter!(Foo); assert(msg2 == exp, msg ~ "\n" ~ exp);
This function produces a descriptive message why R is not an InputRange. If R is an InputRange the returned string will say so.